package com.geek.javase.ch18.videodemo.annotation.book;

import org.junit.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

/*
 *@Date 2025/11/6
 *@Author wangpeng
 *@Description
 *  *  * 一.什么是注解解析
 *  *         * 使用Java技术获得注解上数据的过程则称为注解解析。
 *  *
 *  * 二.与注解解析相关的接口
 *  *         * Annotation: 注解类，该类是所有注解的父类。
 *  *         * AnnotatedElement:该接口定义了与注解解析相关的方法
 *  *              T getAnnotation(Class<T> annotationClass) 根据注解类型获得对应注解对象
 *  *              Annotation[]    getAnnotations() 获得当前对象上使用的所有注解，返回注解数组，包含父类继承的
 *  *              Annotation[]    getDeclaredAnnotations() 获得当前对象上使用的所有注解，返回注解数组,只包含本类的
 *  *              boolean isAnnotationPresent(Class<Annotation> annotationClass) 判断当前对象是否使用了指定的注解，如果使用了则返回true，否则false
 *  *
 *  * 三.获取注解数据的原理
 *  *         * 注解作用在哪个成员上就会得该成员对应的对象来获得注解
 *  *             * 比如注解作用成员方法，则要获得该成员方法对应的Method对象
 *  *             * 比如注解作用在类上，则要该类的Class对象
 *  *             * 比如注解作用在成员变量上，则要获得该成员变量对应的Field对象。
 *  *         * Field,Method,Constructor，Class等类都是实现了AnnotatedElement接口
 *  *
 *  * 四.总结注解解析的步骤
 *  * 1).获取类类型Class对象
 *  * 2).若需要获取Constructor构造器、Method方法、Field属性等上面的注解，则需要先通过Class对象进行获取
 *  * 3).执行其getDeclaredAnnotation(注解.class)，获取注解Annotation对象
 *  * 4).获取注解属性信息 ， 注解.属性()
 */
public class TestAnnotation {
    //解析BookStore类上的@Book注解信息
    @Test
    public void testAnnotationType() {
        //1.获取BookStore的类类型
        Class<BookStore> clazz = BookStore.class;
        //2.获取BookStore类上的指定注解
        Book bookAnnotation = clazz.getAnnotation(Book.class);
        //3.获取Book注解上的属性信息
        System.out.println(bookAnnotation.value());
        System.out.println(bookAnnotation.price());
        System.out.println(Arrays.toString(bookAnnotation.authors()));
    }
    //解析BookStore类、方法上的@Book注解信息
    @Test
    public void testAnnotationMethod() throws NoSuchMethodException {
        //1.获取BookStore的类类型
        Class<BookStore> clazz = BookStore.class;
        //2.获取BookStore类中方法对象
        Method purchaseMethod = clazz.getDeclaredMethod("purchase");
        //3.判断当前方法上，是否有Book注解
        if(purchaseMethod.isAnnotationPresent(Book.class)){
            //4.若有Book注解，则获取方法上注解
            Book bookAnnotation = purchaseMethod.getAnnotation(Book.class);
            //5.获取方法上注解的属性信息
            System.out.println(bookAnnotation.value());
            System.out.println(bookAnnotation.price());
            System.out.println(Arrays.toString(bookAnnotation.authors()));
        }else{
            System.out.println("当前purchase（）方法没有使用Book注解");
        }

    }
}
